// Uncover secrets of  polymorphism.

#include <iostream>
using namespace std;

class A { // There will be a table which content the A::foo of address and B::foo of address
	public:
		virtual void foo( ) { cout << "A::foo" << endl; }
		virtual void bar( ) { cout << "A::bar" << endl; }
};

class B : public A { // There have a table which content B::foo of address and A::bar of address
	public:
		void foo( ) { cout << "B::foo" << endl; }
};

// designer
// ------------------------------------------------------------------
// user

int main( void ) { 
	A a;
	cout << "sizeof( a ) : " << sizeof( a ) << endl;
	B b;
	cout << "sizeof( b ) : " << sizeof( b ) << endl;

	void (**pfunc)() = *((void(***)())&a);
	pfunc[0]();	// A::foo
	pfunc[1]();	// A:bar
	
	void (**pfunc2)() = *((void(***)())&b);
	pfunc2[0]();	// B:foo
	pfunc2[1]();	// A:bar

	A* pa = &b;
	pa->foo( );
	// 1. Find the class b memory from pa.
	// 2. Get the virtual pointer from b memory.
	// 3. Use virtual pointer to make virtual function table.
	// 4. Get the entrance address from virtual function table.
	// 5. Use the entrance to call the function.

	return 0;
}

